package com.authority.service.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.authority.OpServiceException;
import com.authority.common.AdminConstants;
import com.authority.common.MD5Util;
import com.authority.common.UserTypeEnum;
import com.authority.controller.BaseManager;
import com.authority.dao.AuthOrganDAO;
import com.authority.dao.AuthRoleDAO;
import com.authority.dao.AuthUserDAO;
import com.authority.dao.AuthUserDataDao;
import com.authority.dao.AuthUserRoleDAO;
import com.authority.dao.OperationersDAO;
import com.authority.entry.AuthOrganDO;
import com.authority.entry.AuthRoleDO;
import com.authority.entry.AuthSysDO;
import com.authority.entry.AuthUserDO;
import com.authority.entry.AuthUserDataDO;
import com.authority.entry.AuthUserRoleDO;
import com.authority.entry.ext.ExtAuthUserDataDO;
import com.authority.query.UserQuery;
import com.authority.result.PageResult;
import com.authority.service.AuthSysService;
import com.authority.service.AuthUserDataService;
import com.authority.service.UserService;
import com.authority.utils.CommonUtils;
import com.authority.vo.AuthUserVO;
import com.authority.vo.LoginVO;
import com.suixun.dao.SchoolinfoMapper;
import com.suixun.entity.Operationer;
import com.suixun.entity.Schoolinfo;
import com.suixun.util.Constant;
import com.suixun.util.StringUtil;
import com.suixun.util.ipseek.Utils;

@Service("userService")
public class UserServiceImpl implements UserService{
	
	@Resource
	AuthUserDAO userDAO;
	@Resource
	private AuthUserRoleDAO authUserRoleDAO;
	@Resource
	private OperationersDAO operationersDAO;
	@Resource
	private AuthUserDataDao authUserDataDao;
	@Resource
	private SchoolinfoMapper schoolinfoMapper;
	@Resource
	private AuthUserDataService authUserDataService;
	@Resource
	private AuthSysService authSysService;
	@Resource
	private AuthOrganDAO authOrganDAO;
	@Resource
	private AuthRoleDAO authRoleDAO;
	protected final static Logger logger = LoggerFactory.getLogger(UserServiceImpl.class); 
	@Override
	public AuthUserDO queryUserByAccount(String account) {
		return userDAO.querySingleUserByAccount(account);
	}
	
	@Override
	@Transactional
	public String updateUser(AuthUserVO authUserVo) {
		if (authUserVo.getId() == null) {
			return "账户信息不能为空";
		}
		if (authUserVo.isNotAdmin()) {
			editUserByNotAdmin(authUserVo);
		}else {
			if (authUserVo.getOrganId() != null && StringUtil.isNotEmpty(authUserVo.getWorkNumber())) {
				//查询账户是否存在
				Integer id = checkIsExist(authUserVo);
				if(id != null && !String.valueOf(authUserVo.getId()).equals(String.valueOf(id))) {
					return "账户已存在";
				}
			}
			updateUserByAdmin(authUserVo);
			if (StringUtil.isNotBlank(authUserVo.getSchoolid())) {
				editUserByNotAdmin(authUserVo);
			}else {
				checkAndDeleteRegionAuthority(authUserVo.getId());
			}
			if (StringUtil.isNotBlank(authUserVo.getRoleIdList())) {
				//修改账户所属角色
				updateUserRole(authUserVo.getRoleIdList(),authUserVo.getId(),authUserVo.getOperatorId());
			}
		}
		return Constant.SUCCESS;
	}
	
	private void updateUserRole(String roleIds,Long userId,Long operatorId) {
		List<Integer> roleIdList = StringUtil.StringToIntegerList(roleIds, "[|]");
		AuthRoleDO authRoleDo = null;
		if (roleIdList != null) {
			for (Integer roleId : roleIdList) {
				authRoleDo = authRoleDAO.queryAuthRoleById(Long.parseLong(String.valueOf(roleId)));
				if (authRoleDo == null) {
					throw new OpServiceException("角色权限不存在");
				}
				checkAndUpdateUserType(authRoleDo.getCode(),userId);
			}
		}else {
			throw new OpServiceException("角色权限不存在");
		}
		AuthSysDO sys = authSysService.queryAuthSysByCode(AdminConstants.SYSTEM_CODE);
		AuthUserDO authUser = new AuthUserDO();
		authUser.setRoleIdList(roleIds);
		authUser.setId(userId);
		authUser.setOperatorId(operatorId);
		updateUserRole(authUser,sys.getId());
	}
	
	private void checkAndUpdateUserType(String roleCode,Long userId) {
		//如果当前用的角色是包含region的，证明是需要进行区域权限设置的用户
		if (roleCode != null && "salesmanAuthority".equals(roleCode)) {
			//如果是销售人员权限，则将该账户的type置为3
			Map<String,Object> map = new HashMap<>();
			map.put("type", UserTypeEnum.REGIONMAN.getType());
			map.put("id", userId);
			userDAO.updateUser(map);
		}
	}
	
	private void editUserByNotAdmin(AuthUserVO authUserVo) {
		if (authUserVo.getStatus() != null) {
			//非admin用户不能修改用户状态
			throw new OpServiceException("您没有权限");
		}
		Map<String,Object> map = new HashMap<>();
		map.put("userId", authUserVo.getId());
		if (StringUtil.isNotBlank(authUserVo.getSchoolid())) {
			//判断当前用户是否存在区域权限
			List<AuthUserDataDO> userDataList = authUserDataDao.getAuthUserDatasByParam(map);
			if (userDataList.size() == 0) {
				//新增区域权限
				insertUserDataBySchoolids(Integer.parseInt(authUserVo.getId().toString()),authUserVo.getSchoolid()
						,Integer.parseInt(authUserVo.getOperatorId().toString()),authUserVo.getOperatorName());
			}else {
				//修改区域权限
				updateUserDataBySchoolids(Integer.parseInt(authUserVo.getId().toString()),authUserVo.getSchoolid()
						,Integer.parseInt(authUserVo.getOperatorId().toString()),authUserVo.getOperatorName());
			}
			
		}else {
			checkAndDeleteRegionAuthority(authUserVo.getId());
		}
	}
	
	private void checkAndDeleteRegionAuthority(Long userId) {
		//查询区域权限表中是否存在当前权限
		Integer count = authUserDataDao.countByUserId(userId);
		if (count != null && count > 0) {
			//删除当前userId已存在的权限
			authUserDataDao.deleteByUserId(Integer.parseInt(userId.toString()));
		}
	}
	
	private void updateUserDataBySchoolids(Integer userId,String schoolid,Integer operatorId,String operatorName) {
		//删除当前userId已存在的权限
		authUserDataDao.deleteByUserId(userId);
		//新增区域权限
		insertUserDataBySchoolids(userId,schoolid,operatorId,operatorName);
	}
	
	
	private void insertUserDataBySchoolids(Integer userId,String schoolid,Integer operatorId,String operatorName) {
		if (schoolid != null) {
			List<Integer> schoolidList = StringUtil.StringToIntegerList(schoolid, "[|]");
			if (schoolidList != null && schoolidList.size() > 0) {
				for (Integer tempSchoolid : schoolidList) {
					insertUserDataBySchoolid(userId,tempSchoolid,operatorId,operatorName);
				}
			}else {
				throw new OpServiceException("学校id格式不符");
			}
		}
	}
	
	private void insertUserDataBySchoolid(Integer userId,Integer schoolid,Integer operatorId,String operatorName) {
		Schoolinfo schoolInfo = schoolinfoMapper.selectByPrimaryKey(schoolid);
		if (schoolInfo == null) {
			throw new OpServiceException("部分学校不存在");
		}
		if (schoolInfo.getProvince() == null || schoolInfo.getCity() == null || schoolInfo.getTown() == null) {
			throw new OpServiceException(schoolInfo.getSchoolname()+"的省市区为空，请先设置后再操作");
		}
		AuthUserDataDO userData = new AuthUserDataDO();
		userData.setCity(schoolInfo.getCity());
		userData.setGmtCreate(new Date());
		userData.setGmtModified(new Date());
		userData.setOperatorId(operatorId);
		userData.setOperatorName(operatorName);
		userData.setProvince(schoolInfo.getProvince());
		userData.setSchoolId(schoolInfo.getId());
		userData.setTown(schoolInfo.getTown());
		userData.setUserId(userId);
		authUserDataService.insert(userData);
	}
	
	private Integer checkIsExist(AuthUserVO authUserVo) {
		//查询账户是否存在
		Map<String,Object> map = new HashMap<>();
		map.put("organId", authUserVo.getOrganId());
		map.put("workNumber", authUserVo.getWorkNumber());
		map.put("status", authUserVo.getStatus());
		if (authUserVo.getOrganId() != null && StringUtil.isNotBlank(authUserVo.getWorkNumber())) {
			return userDAO.checkAccount(map);
		}
		return null;
	}
	
	private void updateUserByAdmin(AuthUserVO authUserVo) {
		Map<String,Object> map = new HashMap<>();
		map.put("organId", authUserVo.getOrganId());
		map.put("workNumber", authUserVo.getWorkNumber());
		map.put("id", authUserVo.getId());
		map.put("userName", authUserVo.getUserName());
		map.put("tel", authUserVo.getTel());
		map.put("operatorId", authUserVo.getOperatorId());
		map.put("status", authUserVo.getStatus());
		userDAO.updateUser(map);
	}

	@Override
	@Transactional
	public String insertUser(AuthUserVO authUserVo) {
		String checkParamNull = checkParamNull(authUserVo);
		if (!Constant.TRUE.equals(checkParamNull)) {
			return checkParamNull;
		}
		if (!checkOrganIdIsExist(authUserVo.getOrganId())) {
			return "组织机构不存在";
		}
		
		Integer isExist = checkIsExist(authUserVo);
		if(isExist != null){
			return "账号已存在";
		}
		//判断账户是否已经注销
		authUserVo.setStatus(-1);
		Integer id = checkIsExist(authUserVo);
		if (id != null) {
			if (StringUtil.isBlank(authUserVo.getRoleIdList())) {
				throw new OpServiceException("角色权限不能为空");
			}
			//修改账户所属角色
			updateUserRole(authUserVo.getRoleIdList(),Long.parseLong(id.toString()),authUserVo.getOperatorId());
			authUserVo.setStatus(1);
			authUserVo.setId(Long.parseLong(id.toString()));
			updateUserByAdmin(authUserVo);
			if (StringUtil.isNotEmpty(authUserVo.getSchoolid())) {
				insertUserDataBySchoolids(id,authUserVo.getSchoolid(),
						Integer.parseInt(authUserVo.getOperatorId().toString()),authUserVo.getOperatorName());
			}
			return Constant.SUCCESS;
		}
		authUserVo.setPassword(MD5Util.doubleMD5(AdminConstants.DEFAULT_PASSWORD));
		AuthUserDO userDo = new AuthUserDO();
		userDo.setOrganId(authUserVo.getOrganId());
		userDo.setWorkNumber(authUserVo.getWorkNumber());
		userDo.setUserName(authUserVo.getUserName());
		userDo.setTel(authUserVo.getTel());
		userDo.setOperatorId(authUserVo.getOperatorId());
		userDo.setType(authUserVo.getType());
		userDo.setPassword(authUserVo.getPassword());
		userDAO.insertUser(userDo);
		if (StringUtil.isNotBlank(authUserVo.getRoleIdList())) {
			//修改账户所属角色
			updateUserRole(authUserVo.getRoleIdList(),userDo.getId(),authUserVo.getOperatorId());
		}else {
			throw new OpServiceException("角色权限不能为空");
		}
		if (StringUtil.isNotEmpty(authUserVo.getSchoolid())) {
			insertUserDataBySchoolids(Integer.parseInt(String.valueOf(userDo.getId())),authUserVo.getSchoolid(),
					Integer.parseInt(authUserVo.getOperatorId().toString()),authUserVo.getOperatorName());
		}
		return Constant.SUCCESS;
	}
	
	private boolean checkOrganIdIsExist(Long organId) {
		AuthOrganDO organDo = authOrganDAO.queryAuthOrganById(organId);
		if (organDo == null) {
			return false;
		}
		return true;
	}
	
	private String checkParamNull(AuthUserVO authUserVo) {
		if (authUserVo.getOrganId() == null) {
			return "组织机构不能为空";
		}
		if (StringUtil.isEmpty(authUserVo.getWorkNumber())) {
			return "工号不能为空";
		}
		if (StringUtil.isEmpty(authUserVo.getUserName())) {
			return "用户名不能为空";
		}
		if (authUserVo.getOperatorId() == null) {
			return "操作人员不能为空";
		}
		return Constant.TRUE;
	}

	@Override
	public PageResult<AuthUserDO> queryUserListPage(UserQuery query) {
		if(query!=null){
			if(StringUtils.isNotEmpty(query.getUserName())){
				query.setUserName(new StringBuffer().append("%").
						append(query.getUserName()).append("%").toString());
			}
			if(StringUtils.isNotEmpty(query.getTel())){
				query.setTel(new StringBuffer().append("%").
						append(query.getTel()).append("%").toString());
			}
		}
		if (query.isNotAdmin()) {
			//查询当前操作员的organId，非超级管理员只能查看自己部门的人员
			Map<String,Object> map = new HashMap<>();
			map.put("userId", query.getId());
			List<AuthUserDO> userDoList = userDAO.queryUserByParam(map);
			query.setId(null);
			query.setOrganId(userDoList.get(0).getOrganId());
			AuthOrganDO authOrgan = authOrganDAO.queryAuthOrganById(userDoList.get(0).getOrganId());
			if ("销售部".equals(authOrgan.getName()) || "sx".equals(authOrgan.getPrefix())) {
				query.setType(UserTypeEnum.REGIONMAN.getType());
			}
		} 
		PageResult<AuthUserDO> result=new PageResult<AuthUserDO>();
		result.setNum(query.getNum());
		List<AuthUserDO> lists=userDAO.queryUserPage(query);
		query.setIsDownload(true);
		List<AuthUserDO>  lists2=userDAO.queryUserPage(query);
		result.setTotalNum(lists.size());
		result.setList(lists2);
		if (query.isNotAdmin()) {
			result.setNotAdmin(true);
		}
		return result;
	}

	@Override
	public Integer updateUserLastLoginTime(Long id) {
		return userDAO.updateUserLastLoginTime(id);
	}

	@Override
	public LoginVO login(String account, String password) throws Exception {
		
		AuthUserDO db = userDAO.checkAccountAndPassword(account, MD5Util.doubleMD5(password));
		
		if (db == null) {
			throw new OpServiceException("用户名或密码不正确");
		}
		
		if(db.getStatus()==null){
			throw new OpServiceException("用户状态不正确");
		}else if (db.getStatus() == -1) {
			throw new OpServiceException("用户已被删除");
		}else if (db.getStatus() == 2) {
			throw new OpServiceException("用户已被停用");
		}else if (db.getStatus() != 1) {
			throw new OpServiceException("用户状态不正确");
		}
		
		return CommonUtils.dbToVo(db, LoginVO.class);
	}

	@Override
	public AuthUserVO queryUserById(Long uid,boolean checkAuthority) {
		List<Schoolinfo> schoolList = null;
		if (checkAuthority) {
			List<ExtAuthUserDataDO> userDataList = 
					authUserDataDao.getAuthUserDatasWithSchoolByUserId(Integer.parseInt(String.valueOf(uid)));
			if (userDataList != null && userDataList.size() > 0) {
				schoolList = new ArrayList<>();
				Schoolinfo schoolinfo = null;
				for (ExtAuthUserDataDO tempUserData : userDataList) {
					schoolinfo = new Schoolinfo();
					schoolinfo.setSchoolname(tempUserData.getSchoolName());
					schoolinfo.setId(tempUserData.getSchoolId());
					schoolinfo.setProvince(tempUserData.getProvince());
					schoolinfo.setCity(tempUserData.getCity());
					schoolinfo.setTown(tempUserData.getTown());
					schoolList.add(schoolinfo);
				}
			}
		}
		AuthUserDO userDo = userDAO.queryUserById(uid);
		AuthUserVO userVo = new AuthUserVO();
		userVo.setId(userDo.getId());
		userVo.setAccount(userDo.getAccount());
		userVo.setUserName(userDo.getUserName());
		userVo.setOperatorId(userDo.getOperatorId());
		userVo.setStatus(userDo.getStatus());
		userVo.setLastLoginIp(userDo.getLastLoginIp());
		userVo.setTel(userDo.getTel());
		userVo.setWorkNumber(userDo.getWorkNumber());
		userVo.setOrganId(userDo.getOrganId());
		userVo.setOrganName(userDo.getOrganName());
		userVo.setType(userDo.getType());
		if (schoolList != null) {
			userVo.setSchoolList(schoolList);
		}
		//查询当前角色所属权限
		Map<String,Object> map = new HashMap<>();
		map.put("userId", userDo.getId());
		List<AuthRoleDO> roleList = authRoleDAO.queryAuthRoleByUserId(map);
		userVo.setRoleList(roleList);
		return userVo;
	}

	@Override
	public void updatePassword(AuthUserDO db) {
		userDAO.updateUserPassWord(db);
	}
	
	@Override
	public void updatePasswordById(AuthUserDO db) {
		userDAO.updateUserPassWordById(db);
	}
	
	@Override
	public void updatePasswordByAccount(AuthUserDO db) {
		userDAO.updateUserPassWordByAccount(db);
	}
	
	@Override
	@Transactional
	public int updateUserRole(AuthUserDO authUserDO,Long sysId) {
		//AuthUserDO user=userDAO.queryUserById(authUserDO.getId());
		int result=authUserRoleDAO.batchDeleteAuthUserRole(authUserDO.getId(), sysId);
		
		String roleIdList=authUserDO.getRoleIdList();
		if(roleIdList!=null)
		{
			List<AuthUserRoleDO> map=new LinkedList<AuthUserRoleDO>();
			String[] idList=roleIdList.split("\\|");
			for(int i=0;i<idList.length;i++)
			{
				if(idList[i]==null || idList[i].trim().equals(""))
					continue;
				AuthUserRoleDO role=new AuthUserRoleDO();
				role.setRoleId(new Long(idList[i]));
				role.setSysId(sysId);
				role.setUserId(authUserDO.getId());
				role.setOperatorId(authUserDO.getOperatorId());
				map.add(role);
			}
			authUserRoleDAO.batchInsertAuthUserRole(map);
		}

		return result;
	}

	@Override
	public List<AuthUserRoleDO> getUserRole(AuthUserDO authUserDO,Long sysId) {
		// TODO Auto-generated method stub
		return authUserRoleDAO.queryRoleByUserId(authUserDO.getId(), sysId);
	}

	@Override
	public List<AuthUserDO> queryUserByParam(AuthUserDO authUserDO) {
		Map<String,Object> map = new HashMap<>();
		if (authUserDO != null && authUserDO.getOrganId() != 0) {
			map.put("organid", authUserDO.getOrganId());
			return userDAO.queryUserByParam(map);
		}
		return null;
	}
	/**
	 * <p>Title: checkByAppAccount</p>
	 * <p> 功能描述:校验app账号 </p>
	 * @param account
	 * @param password
	 * @return
	 */
	@Override
	public Integer checkByAppAccount(String account, String password) {
		Map<String,Object> map = new HashMap<>();
		map.put("account", account);
		map.put("password", password);
		Operationer operationer = operationersDAO.queryAppAccount(map);
		return operationer == null ? null : operationer.getId();
	}
	/**
	 * <p>Title: updateUserLastLoginIp</p>
	 * <p> 功能描述:修改最后登录ip </p>
	 * @param id
	 * @param request
	 * @return
	 */
	@Override
	public Integer updateUserLastLoginIp(Long id, HttpServletRequest request) {
		String ip = Utils.getIpAddr(request);
	    Map<String,Object> map = new HashMap<>();
	    map.put("ip", ip);
	    map.put("id", id);
	    return userDAO.updateUserLatsLoginIp(map);
	}

	@Override
	public void updateUserAccountByOrganId(Long organId) {
		AuthUserDO authUser = new AuthUserDO();
		authUser.setOrganId(organId);
		List<AuthUserDO> userList = queryUserByParam(authUser);
		if (userList.size() > 0) {
			Map<String,Object> map = new HashMap<>();
			//更新用户的账号
			for (AuthUserDO user : userList) {
				map = new HashMap<>();
				map.put("organid", organId);
				map.put("workNumber", user.getWorkNumber());
				userDAO.updateUserByOrganId(map);
			}
		}
	}

	@Override
	public Integer getNewWorkNumber(AuthUserVO authUserVo) {
		if (authUserVo.getOrganId() == null) {
			return -1;
		}
		Map<String,Object> map = new HashMap<>();
		map.put("organid", authUserVo.getOrganId());
		List<AuthUserDO> userList = userDAO.queryUserByParam(map);
		if (userList.size() == 0) {
			return 1;
		}else {
			List<Integer> list = new ArrayList<>();
			for (AuthUserDO tempUser : userList) {
				list.add(Integer.parseInt(tempUser.getWorkNumber()));
			}
			Collections.sort(list);
			return list.get(list.size()-1) + 1;
		}
	}

	@Override
	@Transactional
	public String deleteUser(Long userId, Long operatorId,boolean checkAuthority) {
		if (userId == null) {
			return "用户不能为空";
		}
		if (operatorId == null) {
			return "操作员不能为空";
		}
		if (checkAuthority) {
			authUserDataDao.deleteByUserId(Integer.parseInt(String.valueOf(userId)));
		}
		Map<String,Object> map = new HashMap<>();
		map.put("id", userId);
		map.put("status", -1);
		map.put("operatorId", operatorId);
		if (userDAO.updateUser(map) == 1) {
			return Constant.SUCCESS;
		}
		return Constant.FAIL;
	}
}
